const fs = require("fs").promises;
const path = require("path");

async function generateSatelliteJson() {
  // 获取初始卫星id
  const initialSatelliteId = Number(process.argv[3]);
  if (isNaN(initialSatelliteId)) {
    console.error("无效的初始卫星id参数");
    return;
  }

  // 修改start参数
  const begin = initialSatelliteId;
  const end = begin + 3;

  const lowOrbitData = await readLowOrbitSatellites(begin, end);
  const neededHighOrbitSatellites = determineNeededHighOrbitSatellites(lowOrbitData);
  const jsonData = buildJsonStructure(lowOrbitData, neededHighOrbitSatellites);
  await saveJsonFile(jsonData, initialSatelliteId);
}

async function readLowOrbitSatellites(begin, end) {
  const satellites = [];
  // 定义轨道偏移量配置
  const orbitOffsets = [0, 88, 176]; // 可以添加更多轨道偏移量

  for (const offset of orbitOffsets) {
    for (let i = begin; i <= end; i++) {
      const fileId = i + offset;
      const fileName = `data${fileId.toString().padStart(4, "0")}.csv`;
      const filePath = path.join(__dirname, "csv", fileName);

      try {
        const data = await fs.readFile(filePath, "utf8");
        const lines = data.trim().split("\n");
        if (lines.length < 2) continue;

        const lineParam = 1;
        const values = lines[lineParam].split(",");
        const lat = parseFloat(values[1]);
        const lon = parseFloat(values[2]);

        if (!isNaN(lat) && !isNaN(lon)) {
          satellites.push({ lat, lon, fileId });
        }
      } catch (error) {
        console.error(`读取文件 ${fileName} 失败:`, error.message);
      }
    }
  }

  return satellites;
}

function determineNeededHighOrbitSatellites(lowOrbitSatellites) {
  const highOrbitSatellites = [
    { id: 1, lon: -120, lat: 0, coverage: { min: -180, max: -60 } },
    { id: 2, lon: 0, lat: 0, coverage: { min: -60, max: 60 } },
    { id: 3, lon: 120, lat: 0, coverage: { min: 60, max: 180 } },
  ];

  return highOrbitSatellites;
}

function buildJsonStructure(lowOrbitSatellites, highOrbitSatellites) {
  const nodes = [];
  const links = [];
  const centerX = 0;
  const centerY = 0;
  const satelliteScaleFactor = 600;
  const baseStationScaleFactor = 500;

  // 添加高轨卫星
  highOrbitSatellites.forEach((hos) => {
    nodes.push({
      id: hos.id,
      name: `高轨卫星${hos.id}`,
      layer: 1,
      x: (hos.lon * satelliteScaleFactor) / 180,
      y: (hos.lat * satelliteScaleFactor) / 90,
      path: "icon/高轨卫星.png",
      abstract: `我是高轨卫星${hos.id}，经度: ${hos.lon}°，纬度: ${hos.lat}°，覆盖范围: ${hos.coverage.min}°至${hos.coverage.max}°`,
      pic: "icon/高轨卫星.png",
    });
  });

  // 添加低轨卫星
  lowOrbitSatellites.forEach((los, index) => {
    const satelliteId = 11 + index;
    const x = (los.lon * satelliteScaleFactor) / 200;
    const y = (los.lat * satelliteScaleFactor) / 60;

    nodes.push({
      id: satelliteId,
      name: `低轨卫星${index + 1}`,
      layer: 2,
      x: centerX + x,
      y: centerY + y,
      path: "icon/低轨卫星.png",
      abstract: `我是低轨卫星${index + 1}，经度: ${los.lon.toFixed(3)}°，纬度: ${los.lat.toFixed(3)}°`,
      pic: "icon/低轨卫星.png",
    });
  });

  // 生成4个地面基站，均匀分布在4个象限
  const baseStationCount = 5;

  // 定义4个象限的经纬度范围
  const quadrants = [
    { lonMin: -180, lonMax: 0, latMin: 0, latMax: 90 }, // 第一象限
    { lonMin: 0, lonMax: 180, latMin: 0, latMax: 90 }, // 第二象限
    { lonMin: -180, lonMax: 0, latMin: -90, latMax: 0 }, // 第三象限
    { lonMin: 0, lonMax: 180, latMin: -90, latMax: 0 }, // 第四象限
  ];

  // 定义4个固定位置的基站坐标
  const fixedBaseStations = [
    { lon: 0, lat: 0 }, // 第一象限
    { lon: -135, lat: 45 }, // 第一象限
    { lon: 135, lat: 45 }, // 第二象限
    { lon: -135, lat: -45 }, // 第三象限
    { lon: 135, lat: -45 }, // 第四象限
  ];

  for (let i = 0; i < baseStationCount; i++) {
    const baseId = 40 + i;
    const baseLon = fixedBaseStations[i].lon;
    const baseLat = fixedBaseStations[i].lat;

    const x = (baseLon * baseStationScaleFactor) / 180;
    const y = (baseLat * baseStationScaleFactor) / 90;

    nodes.push({
      id: baseId,
      name: `用户${i + 1}`,
      layer: 3,
      x,
      y,
      path: "icon/用户.png",
      abstract: `我是用户${i + 1}，经度: ${baseLon.toFixed(3)}°，纬度: ${baseLat.toFixed(3)}°`,
      pic: "icon/用户.png",
    });
  }

  // 建立连接关系
  // 1. 高轨卫星 → 低轨卫星（根据覆盖范围）
  lowOrbitSatellites.forEach((los, index) => {
    const satelliteId = 11 + index;

    // 找到覆盖此低轨卫星的高轨卫星
    const coveringHighOrbit = highOrbitSatellites.find(
      (hos) => los.lon >= hos.coverage.min && los.lon <= hos.coverage.max
    );

    if (coveringHighOrbit) {
      links.push({
        source: coveringHighOrbit.id,
        target: satelliteId,
        layer: 4,
      });
    }
  });

  // 2. 地面基站 → 低轨卫星（每个基站连接最近的低轨卫星）
  const baseStations = nodes.filter((node) => node.layer === 3);

  baseStations.forEach((base) => {
    // 计算到所有低轨卫星的距离
    const distances = lowOrbitSatellites.map((los, index) => {
      const satelliteId = 11 + index;
      const satelliteNode = nodes.find((n) => n.id === satelliteId);

      const dx = satelliteNode.x - base.x;
      const dy = satelliteNode.y - base.y;

      return {
        id: satelliteId,
        distance: Math.sqrt(dx * dx + dy * dy),
      };
    });
    console.log(distances);

    // 找到最近的低轨卫星并连接
    const nearestSatellite = distances.reduce((min, curr) => (curr.distance < min.distance ? curr : min));
    console.log(nearestSatellite);

    // 注意：这里source是基站，target是卫星
    links.push({
      source: base.id,
      target: nearestSatellite.id,
      layer: 4,
    });
  });

  // 验证没有高轨卫星直接连接基站的情况
  const invalidLinks = links.filter((link) => {
    const sourceLayer = nodes.find((n) => n.id === link.source)?.layer;
    const targetLayer = nodes.find((n) => n.id === link.target)?.layer;

    // 高轨卫星(layer=1)不应该直接连接基站(layer=3)
    return (sourceLayer === 1 && targetLayer === 3) || (sourceLayer === 3 && targetLayer === 1);
  });

  if (invalidLinks.length > 0) {
    console.error(`发现 ${invalidLinks.length} 条非法连接，已自动移除`);
    // 过滤掉非法连接
    links = links.filter((link) => !invalidLinks.includes(link));
  }

  return { nodes, links };
}

async function saveJsonFile(data, initialSatelliteId) {
  const jsonContent = JSON.stringify(data, null, 2);
  const fileName = `./json/satellite-topology-${initialSatelliteId}.json`;
  await fs.writeFile(path.join(__dirname, fileName), jsonContent);
  console.log(`JSON文件已生成：${fileName}`);
}

generateSatelliteJson().catch(console.error);
